In [ ]:
IJulia.set_verbose()

Manual Test Notebook

Run each cell, check for expected behaviour and check the browser console for errors


In [ ]:
using Interact

In [ ]:
#Dependent sliders
# first and second numbers (signal(first_slider) and sval) should update if you move the sin slider (before moving x)
# but shouldn't update after you move the x slider
# second two (sval and cval) should update always

x = slider(0:.1:2pi, label="x")
s = map(a -> slider(-1:.05:1, value=sin(2a), label="sin(2x)"), signal(x))
c = map(a -> slider(-1:.05:1, value=cos(2a), label="cos(2x)"), signal(x))
sval = flatten(map(w->signal(w), signal(s); typ=Signal); typ=Any)
cval = flatten(map(w->signal(w), signal(c); typ=Signal); typ=Any)
first_slider = value(s)
map(display, [x,s,c,signal(first_slider), sval, cval]);

In [ ]:
#Signal{Widget} display, updating - move the slider, click "checkbox", click the checkbox - stuff should update
widget_choice = togglebuttons(["slider","checkbox"], label="choose a widget")
slider_to_show = slider(1:10; label="killr slider")
checkbox_to_show = checkbox(true; label="my new checkcheck")
widget_chosen = map(x->x=="slider"? slider_to_show : checkbox_to_show, signal(widget_choice); typ=Widget);

map(display, (widget_choice, widget_chosen, signal(checkbox_to_show), signal(slider_to_show)));

In [ ]:
#these should be in sync with the above, but disappear when you click the widget selector above
map(display, (checkbox_to_show, slider_to_show));

In [ ]:
#Same again but creating a new slider each time, plus flatten
count = 0
widget_choice = togglebuttons(["slider","checkbox"], label="choose a widget")
widget_chosen = map(signal(widget_choice); typ=Widget) do x
    global count += 1; 
    x=="slider"? slider(1:10; label="killr slider $count") : checkbox(true; label="my new checkcheck $count") 
end;

chosen_val = flatten(map(w->signal(w), widget_chosen; typ=Signal); typ=Any)
map(display, (widget_choice, widget_chosen, chosen_val));

In [ ]:
#check sync as above
chosen_val = flatten(map(w->signal(w), widget_chosen; typ=Signal); typ=Any)
map(display, (widget_choice, widget_chosen, chosen_val));

In [ ]:
#Signal{Widget} with same Widget type
#buttons sometimes out of order is ipywidgets issue
eb=togglebuttons([1,2,3])
display(eb)
uuid=[[0,1],[0,1,2],[0,2]]
ub = map(x->togglebuttons(uuid[x]),eb.signal)
ub40 = flatten(map(w->signal(w), signal(ub); typ=Signal); typ=Any)
display.([ub, ub40]);

In [ ]:
#Slider options: vertical, no readout 
s1 = slider(-1:.05:1, value=sin(2), label="vert", orientation="vertical")
s2 = slider(-1:.05:1, value=sin(2), label="no readout", signal=signal(s1), orientation="horizontal", readout=false)
display.([s1,s2]);

In [ ]:
pboy = progress() #should show all grey, then some colour when you run the cell below

In [ ]:
update!(pboy,50)

In [ ]:
# Select Slider with value set via textbox, type 9, 99, 999, 9999
# Value should be the value from the textbox, changes in slider should update teh textbox and vice-versa 

exprange = map(x->2^x,1:0.01:10)
init_val = first(exprange)

#create slider
expslide = selection_slider(exprange, label="exponential value")

#create textbox
txtbox = textbox(string(init_val); label="set slider value")
nearest(arr, val) = indmin(abs(val .- arr))

#holds the last valid float value of what's in the textbox
output_valsig = foldp(init_val, signal(txtbox)) do prev, txt
    val = tryparse(Float64, txt)
    isnull(val) ? prev : get(val)
end

#find the nearest value to what's in the textbox, and update the slider's signal with it 
map(output_valsig) do val
    idx = nearest(exprange, val)
    if value(signal(expslide)) != exprange[idx]
        push!(signal(expslide), exprange[idx])
    end
end |> preserve

#if the slider moves, update the txt box
map(signal(expslide)) do sliderval
    if nearest(exprange, value(output_valsig)) != nearest(exprange, sliderval)
        push!(signal(txtbox), string(sliderval))
    end
end |> preserve

#display the widgets and the slider's signal's value
display.([expslide, txtbox, signal(expslide), signal(txtbox), signal(output_valsig)]);

In [ ]:
push!(signal(expslide), 30) #should update textbox and slider

In [ ]:
push!(signal(txtbox), "50") #should update textbox and slider

In [ ]:
# Same but vertical selection_slider, Float64 checkbox, shared signal, and textbox value set.
# Value should be the value from the textbox, changes in slider should update the textbox and vice-versa 

expslide = selection_slider(2.^(1:0.01:10), label="exponential value"; orientation="vertical")
valsig = signal(expslide)
txtbox = textbox(30.0; label="entired desired value", signal=valsig)
display.([expslide, txtbox, valsig]);

In [ ]:
# multi-select - ctrl/cmd or shift click for multiple values
mse = selection(enumerate(["fred",2,1 + 0.5im, 0.3]) |> collect, multi=true)
ms = selection(["fred",2,1 + 0.5im, 0.3], multi=true)
display.([ms,signal(ms)]);
# display.([mse,signal(mse)]); Currently broken, should work;

In [ ]:
ss = selection(11:20)
display.([ss,signal(ss)]);

In [ ]:
# Update options value_label displayed by pushing value to signal, run cell below
fmult = Signal(Float64, 1e9) #GHz
w_fmult = togglebuttons([("kHz", 1e3), ("MHz", 1e6), ("GHz", 1e9)], value=value(fmult), signal=fmult)
display.([w_fmult, signal(w_fmult)]);

In [ ]:
#run this multiple times, val should match selected toggle button
val = rand([1e3,1e6,1e9])
push!(fmult, val)
val

In [ ]:
#slider stays synced with sig, use cell below
s4 = slider(12:20)
display.([s4, signal(s4)]);

In [ ]:
#slider above should move to 13
push!(signal(s4), 13)
update_view(s4)

In [ ]:
#syncsig=false doesn't stay synced with sig, use cell below
s5 = slider(12:20; syncsig=false)
display.([s5, signal(s5)]);

In [ ]:
#slider above *shouldn't* move to 13, but signal below should show 13
push!(signal(s5), 13)
update_view(s5)

In [ ]:
# Print during update (when slider moves)
@manipulate for i in 1:10
    @show i
end

In [ ]:
#byo signal
ss = Signal(3)
s1= slider(0:10; signal=ss)
map(display, (s1,ss));

In [ ]:
#Byo Signal and init value
fx = Signal(0.0)
x = slider(0:.1:2pi, label="x")
y = map(v -> slider(-1:.05:1, value=sin(v), signal=fx, label="sin(x)"), signal(x))
#init value only
z = map(a -> slider(-1:.05:1, value=sin(2a), label="sin(2x)"), signal(x))
ssz = flatten(map(zslider->signal(zslider), signal(z)))
sinx = map(xv->round(sin(xv), 3), signal(x))
sin2x = map(xv->round(sin(2xv), 3), signal(x))
#top 3 values should be the same as the slider readouts after you move x (but not the other 2 sliders)
#next two should be ~= sliders 2 and 3 at all times
display.([x, y, z, signal(x), sinx, sin2x, fx, ssz]);

In [ ]:
#layout
cb = checkbox();
s1 = slider(1:10; orientation="vertical"); 
s2 = slider(11:0.1:20; orientation="vertical"); 
layout = hbox(vbox(s1,cb), s2)
display.([layout, map(signal, (cb,s1,s2))...]);

In [ ]:
#sin and cos are types that are subtypes of Function, make sure Options can generalise inputs to be of type Function
#clicking the buttons should update the "sin (generic function with 10 methods)" output
using Interact
t = togglebuttons([sin,cos])
display.([t, signal(t), eltype(signal(t))])
@show typeof.([sin,cos]);

In [ ]:
sldmin = slider(0:.01:10.0, label="min value")
sldstep = slider(0.01:.01:1, label="step size")
sldmax = slider(10.0:.1:20.0, label="max value")
sldrange = map((vmin, vstep, vmax)->vmin:vstep:vmax, signal(sldmin), signal(sldstep), signal(sldmax))
s1 = slider(.01:.5:15.0)
set!(s1, :range, sldrange)
display.([sldmin, sldstep, sldmax, s1, sldrange]);

In [ ]: